﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lucene.Net.Analysis;
using LWrap.Interfaces;
namespace LWrap.CustomLWrapps
{
    public class SynonymPhraseStopWordFilter:TokenFilter
    {
        Stack<Token> _injectedTockensStack = null;
        Token _previousToken = null;
        ISynonymsCache _synonymCache = null;
        IPhraseaCache _phraseCache = null;

        public SynonymPhraseStopWordFilter(TokenStream inputStream, ISynonymsCache synCache, IPhraseaCache phraseCache):base(inputStream)
        {
            this._synonymCache = synCache;
            this._phraseCache = phraseCache;
            this._injectedTockensStack = new Stack<Token>();
        }

        public override Token Next()
        {
            if (this._injectedTockensStack.Count > 0)
                return this._injectedTockensStack.Pop();

            Token token = input.Next();
            if (token != null)
            {
                string phrase = InjectPhrases(token);
                InjectSynonyms(token.TermText(), token);
                InjectSynonyms(phrase, token);
                this._previousToken = token;
            }
            return base.Next();
        }

        private string InjectPhrases(Token currentToken)
        {
            if (this._previousToken != null)
            {
                string phrase = this._previousToken.TermText() + " " + currentToken.TermText();
                if (this._phraseCache.IsValidPhrase(phrase))
                {
                    Token phraseToken = new Token(phrase,
                    currentToken.StartOffset(),
                    currentToken.EndOffset(), "phrase");
                    phraseToken.SetPositionIncrement(0);
                    this._injectedTockensStack.Push(phraseToken);
                    return phrase;
                }
            }
            return null;
        }

        private void InjectSynonyms(String text, Token currentToken)
        {
            if (text != null)
            {
                List<String> synonyms = this._synonymCache.GetSynonym(text);
                if (synonyms != null)
                {
                    foreach (string synonym in synonyms)
                    {
                        Token synonymToken = new Token(synonym, currentToken.StartOffset(), currentToken.EndOffset(), "synonym");
                        synonymToken.SetPositionIncrement(0);
                        this._injectedTockensStack.Push(synonymToken);
                    }
                }
            }
        }

    }
}
